// 版权所有2009 Go作者。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// Windows系统调用。

package syscall

import (
	errorspkg "errors"
	"internal/itoa"
	"internal/oserror"
	"internal/race"
	"internal/unsafeheader"
	"runtime"
	"sync"
	"unicode/utf16"
	"unsafe"
)

type Handle uintptr

const InvalidHandle = ^Handle(0)

// StringToUTF16返回UTF-8字符串s的UTF-16编码，
// 并添加终止NUL。如果s包含一个NUL字节，则此
// 函数将崩溃，而不是返回错误。
// 
// 已弃用：改用UTF16FromString。
func StringToUTF16(s string) []uint16 {
	a, err := UTF16FromString(s)
	if err != nil {
		panic("syscall: string with NUL passed to StringToUTF16")
	}
	return a
}

// UTF16FromString返回UTF-8字符串
// s的UTF-16编码，并添加一个终止NUL。如果s在任何
// 位置包含NUL字节，则返回（nil，EINVAL）。
func UTF16FromString(s string) ([]uint16, error) {
	for i := 0; i < len(s); i++ {
		if s[i] == 0 {
			return nil, EINVAL
		}
	}
	return utf16.Encode([]rune(s + "\x00")), nil
}

// UTF16ToString返回UTF-16序列s的UTF-8编码，
// ，并删除终止NUL。
func UTF16ToString(s []uint16) string {
	for i, v := range s {
		if v == 0 {
			s = s[0:i]
			break
		}
	}
	return string(utf16.Decode(s))
}

// utf16PtrToString类似于UTF16ToString，但将*uint16 
// 作为参数，而不是[]uint16。
func utf16PtrToString(p *uint16) string {
	if p == nil {
		return ""
	}
	// 查找NUL终止符。
	end := unsafe.Pointer(p)
	n := 0
	for *(*uint16)(end) != 0 {
		end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p))
		n++
	}
	// 将*uint16转换为[]uint16。
	var s []uint16
	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&s))
	hdr.Data = unsafe.Pointer(p)
	hdr.Cap = n
	hdr.Len = n
	// 将[]uint16解码为字符串。
	return string(utf16.Decode(s))
}

// StringToUTF16Ptr返回指向
// UTF-8字符串s的UTF-16编码的指针，并添加一个终止NUL。如果s 
// 包含一个NUL字节，则此函数将崩溃，而不是返回一个错误。
// 
// 已弃用：改用UTF16PtrFromString。
func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }

// UTF16PtrFromString返回指向
// UTF-8字符串s的UTF-16编码的指针，并添加一个终止NUL。如果s 
// 在任何位置包含NUL字节，则返回（nil，EINVAL）。
func UTF16PtrFromString(s string) (*uint16, error) {
	a, err := UTF16FromString(s)
	if err != nil {
		return nil, err
	}
	return &a[0], nil
}

// Errno是Windows错误号。
// 
// Errno值可以根据操作系统包
// using errors.Is中的错误值进行测试。例如：
// 
// ，u，err:=syscall.syscall（…）
// /if errors.Is（err，fs.ErrNotExist）。。。
type Errno uintptr

func langid(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) }

// FormatMessage已弃用（msgsrc应为uintptr，而不是uint32，但由于Go 1兼容性保证，不能更改
// ）。
// 
// 已弃用：请改用golang.org/x/sys/windows中的FormatMessage。
func FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
	return formatMessage(flags, uintptr(msgsrc), msgid, langid, buf, args)
}

func (e Errno) Error() string {
	// 处理特殊go错误
	idx := int(e - APPLICATION_ERROR)
	if 0 <= idx && idx < len(errors) {
		return errors[idx]
	}
	// 向windows询问剩余错误
	var flags uint32 = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_IGNORE_INSERTS
	b := make([]uint16, 300)
	n, err := formatMessage(flags, 0, uint32(e), langid(LANG_ENGLISH, SUBLANG_ENGLISH_US), b, nil)
	if err != nil {
		n, err = formatMessage(flags, 0, uint32(e), 0, b, nil)
		if err != nil {
			return "winapi error #" + itoa.Itoa(int(e))
		}
	}
	// 修剪终止\r和\n 
	for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- {
	}
	return string(utf16.Decode(b[:n]))
}

const _ERROR_BAD_NETPATH = Errno(53)

func (e Errno) Is(target error) bool {
	switch target {
	case oserror.ErrPermission:
		return e == ERROR_ACCESS_DENIED
	case oserror.ErrExist:
		return e == ERROR_ALREADY_EXISTS ||
			e == ERROR_DIR_NOT_EMPTY ||
			e == ERROR_FILE_EXISTS
	case oserror.ErrNotExist:
		return e == ERROR_FILE_NOT_FOUND ||
			e == _ERROR_BAD_NETPATH ||
			e == ERROR_PATH_NOT_FOUND
	}
	return false
}

func (e Errno) Temporary() bool {
	return e == EINTR || e == EMFILE || e.Timeout()
}

func (e Errno) Timeout() bool {
	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
}

// 在运行时/syscall\u windows.go中实现。
func compileCallback(fn interface{}, cleanstack bool) uintptr

// NewCallback将Go函数转换为符合stdcall调用约定的函数指针。
// 这在与需要回调的Windows代码进行互操作时非常有用。
// 参数应为具有一个uintptr大小结果的函数。函数的参数大小不得大于uintptr的大小。
// 在一个Go进程中只能创建有限数量的回调，并且永远不会释放为这些回调分配的任何内存。
// 在NewCallback和NewCallbackCDecl之间，至少可以创建1024个回调。
func NewCallback(fn interface{}) uintptr {
	return compileCallback(fn, true)
}

// NewCallbackCDecl将Go函数转换为符合cdecl调用约定的函数指针。
// 这在与需要回调的Windows代码进行互操作时非常有用。
// 参数应为具有一个uintptr大小结果的函数。函数的参数大小不得大于uintptr的大小。
// 在一个Go进程中只能创建有限数量的回调，并且永远不会释放为这些回调分配的任何内存
// 。
// 在NewCallback和NewCallbackCDecl之间，至少可以创建1024个回调。
func NewCallbackCDecl(fn interface{}) uintptr {
	return compileCallback(fn, false)
}

// windows api调用

// sys GetLastError（）（LastError）
// sys LoadLibrary（libname字符串）（句柄句柄，错误）=LoadLibraryW 
// sys FreeLibrary（句柄）（错误）
// sys GetProcAddress（模块句柄，procname字符串）（proc uintptr，错误）
// sys GetVersion（）（版本uint32，错误）
// sys rtlGetNtVersionNumbers（主版本*uint32，最小版本*uint32，建筑编号*uint32）=ntdll.rtlGetNtVersionNumbers 
// sys formatMessage（标志uint32，msgsrc uintptr，msgid uint32，langid uint32，buf[]uint16，参数*字节）（n uint32，错误）=FormatMessageW 
// sys ExitProcess（exitcode uint32）
// sys CreateFile（name*uint16，access uint32，mode uint32，sa*SecurityAttributes，createmode uint32，attrs uint32，templatefile int32）（句柄，错误）[failretval==InvalidHandle]=CreateFileW 
// sys WriteFile（句柄句柄，buf[]字节，done*uint32，overlapped*overlapped）（错误）
// sys SetFilePointer（句柄句柄，lowoffset int32，highoffsetptr*int32，where uint32）（newlowoffset uint32，error error）[failretval==0xffffffffff]
// sys CloseHandle（句柄）（错误）
// sys-GetStdHandle（stdhandle int）（句柄，错误）[failretval==InvalidHandle]
// /sys-findFirstFile1（名称*uint16，数据*win32finddata1）（句柄句柄，错误）[failretval==InvalidHandle]=FindFirstFileW 
// sys findNextFile1（句柄，数据*win32finddata1）（错误）=FindNextFileW 
// sys-FindClose（句柄句柄）（错误）
// sys-GetFileInformationByHandle（句柄句柄句柄，数据*字节句柄文件信息）（错误）
// sys-GetCurrentDirectory（buflen-uint32，buf*uint16）（n-uint32，错误）=GetCurrentDirectoryW-
// sys SetCurrentDirectory（路径*uint16）（错误）=SetCurrentDirectoryW 
// sys CreateDirectory（路径*uint16，sa*安全属性）（错误）=CreateDirectoryW 
// sys RemoveDirectory（路径*uint16）（错误）=RemoveDirectoryW 
// sys DeleteFile（路径*uint16）（错误）=DeleteFileW 
// sys MoveFile（从*uint16到*uint16）（error error）=MoveFileW 
// sys GetComputerName（buf*uint16，n*uint32）（error error）=GetComputerNameW 
// sys SetEndOfFile（handle handle）（error error）
// sys GetTimeZoneInformation（tzi*Timezoneinformation）（rc uint32，error error）[failretval==0xffffffff]
// sys createIoCompletionPort（filehandle Handle，cphandle Handle，key uintptpr，threadcnt uint32）（Handle Handle，error error）=createIoCompletionPort 
// sys getQueuedCompletionStatus（cphandle，qty*uint32，key*uintpr，overlapped**overlapped，timeout uint32）（错误）=GetQueuedCompletionStatus 
// sys postQueuedCompletionStatus（cphandle句柄，数量uint32，键uintptr，重叠*重叠）（错误）=postQueuedCompletionStatus 
// sys CancelIo（s句柄）（错误）
// sys CancelIoEx（s句柄，o*重叠）（错误）
// sys CreateProcess（appName*uint16、commandLine*uint16、procSecurity*SecurityAttributes、threadSecurity*SecurityAttributes、inheritHandles bool、creationFlags uint32、env*uint16、currentDir*uint16、startupInfo*startupInfo、outProcInfo*ProcessInformation）（错误）=CreateProcessW 
// sys CreateProcessAsUser（令牌令牌、appName*uint16、命令行*uint16、procSecurity*SecurityAttributes、threadSecurity*SecurityAttributes、inheritHandles bool、creationFlags uint32、env*uint16、currentDir*uint16、startupInfo*startupInfo、outProcInfo*ProcessInformation）（错误）=advapi32.createProcessASERW 
// sys OpenProcess（da uint32，inheritHandle bool，pid uint32）（句柄句柄，错误）
// sys TerminateProcess（句柄句柄，exitcode uint32）（错误）
// sys getExidProcess（句柄，exitcode*uint32）（错误）
// sys GetCurrentProcess（）（伪句柄，错误）
// sys GetProcessTimes（句柄，creationTime*Filetime，exitTime*Filetime，kernelTime*Filetime，userTime*Filetime）（错误）
// sys DuplicateHandle（hSourceProcessHandle，hSourceHandle，htTargetProcessHandle，lpTargetHandle*Handle，dwDesiredAccess uint32，BinherithHandle bool，dwOptions uint32）（错误）
// sys WaitForSingleObject（句柄，WaitForSingleObject）（事件uint32，错误）[failretval==0xffffffff]
// sys GetTempPath（buflen uint32，buf*uint16）（n uint32，error error）=gettempathw 
// sys CreatePipe（readhandle*Handle，writehandle*Handle，sa*SecurityAttributes，size uint32）（error error）
// sys CryptReleaseContext（provhandle，flags uint32）（错误）=advapi32.CryptReleaseContext 
// sys CryptGenRandom（provhandle句柄，buflen uint32，buf*字节）（错误）=advapi32.CryptGenRandom 
// sys-GetEnvironmentStrings（）（envs*uint16，错误）[failretval==nil]=kernel32.GetEnvironmentStringsW 
// sys-FreeEnvironmentStrings（envs*uint16）（错误）=kernel32.FreeEnvironmentStringsW 
// sys-GetEnvironmentVariable（name*uint16，buffer*uint16，size uint32）（n uint32，err error）=内核32.GetEnvironment变量
// sys SetEnvironmentVariable（name*uint16，value*uint16）（error error）=kernel32.SetEnvironmentVariable 
// sys SetFileTime（handle handle，ctime*Filetime，atime*Filetime，wtime*Filetime）（error error error）
// sys SetFileAttributes（name*uint16，attrs uint32）（error error）=kernel32.SetFileAttributesW 
// sys GetFileAttributesEx（name*uint16，level uint32，info*byte）（error）=kernel32.GetFileAttributesExW 
// sys CommandLineToArgv（cmd*uint16，argc*int32）（argv*[8192]*[8192]uint16，error error error）[failretval==nil]=shell32.CommandLineToArgvW 
// sys LocalFree（hmem Handle）（Handle Handle，error）[failretval！=0]
// sys sethandle（句柄句柄，掩码uint32，标志uint32）（错误错误）
// sys FlushFileBuffers（句柄句柄）（错误）
// sys GetFullPathName（路径*uint16，buflen uint32，buf*uint16，fname**uint16）（n uint32，错误）=kernel32.GetFullPathNameW 
// sys GetLongPathName（路径*uint16，buf*uint16，buflen uint32）（n uint32，error error）=kernel32.GetLongPathNameW 
// sys GetShortPathName（longpath*uint16，shortpath*uint16，buflen uint32）（n uint32，error error）=kernel32.GetShortPathNameW 
// sys CreateFileMapping（fhandle句柄，sa*SecurityAttributes，prot uint32，maxSizeHigh uint32，maxSizeLow uint32，name*uint16）（handle handle，err error）=kernel32.CreateFileMappingW 
// sys-MapViewOfFile（handle handle，access uint32，offsetHigh uint32，offsetLow uint32，length uintpttr）（addr uintpttr，error error）
// sys VirtualLock（地址uintpttr，长度uintpttr）（错误）
// sys VirtualLock（地址uintpttr，长度uintpttr）（错误）
// sys TransmitFile（s句柄，句柄，bytesToWrite uint32，BytPersend uint32，重叠*重叠，TransmitFileBuff*TransmitFileBuffers，标志uint32）（错误）=mswsock.TransmitFile 
// sys ReadDirectoryChanges（句柄句柄，buf*字节，buflen uint32，watchSubTree bool，mask uint32，retlen*uint32，overlapped*overlapped，completionRoutine uintptpr）（error error error）=kernel32.ReadDirectoryChangesW 
// sys CertOpenSystemStore（hprov句柄，name*uint16）（存储句柄，error error）=crypt32.CertOpenSystemStoreW 
// sys CertOpenStore（storeProvider uintptr，msgAndCertEncodingType uint32，cryptProv UINTPTTR，flags uint32，para uintptr）（句柄，错误）=crypt32.CertOpenStore 
// sys CertEnumCertificateSinstare（store句柄，prevContext*CertContext）（context*CertContext，错误）[failretval==nil]=crypt32.CertEnumCertificateSinstare 
// sys CertAddCertificateContextToStore（存储句柄，certContext*certContext，addDisposition uint32，存储上下文**certContext）（错误）=crypt32.CertAddCertificateContextToStore 
// sys CertGetCertificateChain（引擎句柄、叶*CertContext、时间*Filetime、附加存储句柄、para*CertChainPara、标志uint32、保留uintptr、chainCtx**CertChainContext）（错误）=crypt32.CertGetCertificateChain 
// sys CertFreeCertChainCertificateChain（ctx*CertChainContext）=crypt32.CertFreeCertificateChain 
// sys-CertCreateCertificateContext（certEncodingType uint32，certEncoded*byte，encodedLen uint32）（context*CertContext，error error）[failretval==nil]=crypt32.CertCreateCertificateContext 
// sys CertVerifyCertificateChainPolicy（policyOID uintptr，chain*CertChainContext，para*CertChainPolicyPara，status*CertChainPolicyStatus）（错误）=crypt32.CertVerifyCertificateChainPolicy 
// sys RegOpenKeyEx（键句柄，子键*uint16，选项uint32，期望访问uint32，结果*Handle）（regerrno error）=advapi32.RegOpenKeyExW 
// sys RegCloseKey（键句柄）（regerrno error）=advapi32.RegCloseKey 
// sys RegQueryInfoKey（键句柄，class*uint16，classLen*uint32，reserved*uint32，SubKeyLen*uint32，maxSubkeyLen*uint32，maxClassLen*uint32，valuesLen*uint32，maxValueNameLen*uint32，maxValueLen*uint32，saLen*uint32，lastWriteTime*Filetime）（regerrno错误）=advapi32.RegQueryInfoKeyW 
// sys RegQueryValueEx（键句柄，名称*uint16，保留*uint32，valtype*uint32，buf*字节，buflen*uint32）（regerrno error）=advapi32.RegQueryValueExW 
// sys getCurrentProcessId（）（pid uint32）=kernel32.getCurrentProcessId 
// sys GetConsoleMode（控制台句柄，mode*uint32）（错误）=kernel32.GetConsoleMode 
// sys WriteConsole（控制台句柄，buf*uint16，towrite uint32，writed*uint32，reserved*字节）（错误）=kernel32.WriteConsole 
// sys ReadConsole（控制台句柄，buf*uint16，toread uint32，read*uint32，inputControl*字节）（错误）=kernel32.ReadConsoleW 
// sys CreateToolhelp32Snapshot（标志uint32，processId uint32）（句柄，错误）[failretval==InvalidHandle]=kernel32.CreateToolhelp32Snapshot 
// sys Process32First（快照句柄，procEntry*ProcessEntry32）（错误）=kernel32.Process32FirstW 
// sys Process32Next（快照句柄，procEntry*ProcessEntry32）（错误）=kernel32.Process32NextW 
// /sys devicecontrol（句柄句柄，ioControlCode uint32，inBuffer*字节，inBufferSize uint32，extuffer*字节，extufferSize uint32，byteReturned*uint32，overlapped*overlapped）（错误）
// 此函数返回1字节的布尔值，而不是4字节的布尔值。
// sys CreateSymbolicLink（symlinkfilename*uint16，targetfilename*uint16，flags uint32）（错误）[failretval&0xff==0]=createSymbolicLinkKW 
// sys CreateHardLink（filename*uint16，existingfilename*uint16，reserved uintpttr）（错误）[failretval&0xff==0]=CreateHardLinkW 
// /sys initializeProcThreadAttributeList（attrlist*\u PROC\u THREAD\u ATTRIBUTE\u LIST，attrcount uint32，flags uint32，size*uintpttr）（错误）=InitializeProcThreadAttributeList 
// sys deleteProcThreadAttributeList（attrlist*.\u PROC\u THREAD\u ATTRIBUTE\u LIST）=deleteProcThreadAttributeList 
// sys updateProcThreadAttributeList（attrlist*\u PROC\u THREAD\u ATTRIBUTE\u LIST，标志uint32，attr uintpttr，值不安全。指针，大小uintpttr，prevvalue不安全。指针，返回的大小*uintpttr）（错误）=UpdateProcThreadAttribute 

// 其他软件包的系统调用接口实现

func makeInheritSa() *SecurityAttributes {
	var sa SecurityAttributes
	sa.Length = uint32(unsafe.Sizeof(sa))
	sa.InheritHandle = 1
	return &sa
}

func Open(path string, mode int, perm uint32) (fd Handle, err error) {
	if len(path) == 0 {
		return InvalidHandle, ERROR_FILE_NOT_FOUND
	}
	pathp, err := UTF16PtrFromString(path)
	if err != nil {
		return InvalidHandle, err
	}
	var access uint32
	switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
	case O_RDONLY:
		access = GENERIC_READ
	case O_WRONLY:
		access = GENERIC_WRITE
	case O_RDWR:
		access = GENERIC_READ | GENERIC_WRITE
	}
	if mode&O_CREAT != 0 {
		access |= GENERIC_WRITE
	}
	if mode&O_APPEND != 0 {
		access &^= GENERIC_WRITE
		access |= FILE_APPEND_DATA
	}
	sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
	var sa *SecurityAttributes
	if mode&O_CLOEXEC == 0 {
		sa = makeInheritSa()
	}
	var createmode uint32
	switch {
	case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
		createmode = CREATE_NEW
	case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
		createmode = CREATE_ALWAYS
	case mode&O_CREAT == O_CREAT:
		createmode = OPEN_ALWAYS
	case mode&O_TRUNC == O_TRUNC:
		createmode = TRUNCATE_EXISTING
	default:
		createmode = OPEN_EXISTING
	}
	var attrs uint32 = FILE_ATTRIBUTE_NORMAL
	if perm&S_IWRITE == 0 {
		attrs = FILE_ATTRIBUTE_READONLY
		if createmode == CREATE_ALWAYS {
			// 我们被要求创建一个只读文件。
			// 如果文件已经存在，
			// Unix开放系统调用的语义是保留
			// 现有权限。I如果我们将CREATE始终
			// 和FILE属性READONLY传递给CreateFile，
			// 并且文件已经存在，CreateFile将
			// 更改文件权限。
			// 避免这样做以保留Unix语义。
			h, e := CreateFile(pathp, access, sharemode, sa, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
			switch e {
			case ERROR_FILE_NOT_FOUND, _ERROR_BAD_NETPATH, ERROR_PATH_NOT_FOUND:
				// 文件不存在。这些都是相同的
				// 错误为Errno.Is检查ErrNotExist.
				// 继续创建文件。
			default:
				// 成功或其他错误。
				return h, e
			}
		}
	}
	h, e := CreateFile(pathp, access, sharemode, sa, createmode, attrs, 0)
	return h, e
}

func Read(fd Handle, p []byte) (n int, err error) {
	var done uint32
	e := ReadFile(fd, p, &done, nil)
	if e != nil {
		if e == ERROR_BROKEN_PIPE {
			// 注意（brainman）：从stdin 
			return 0, nil
		}
		return 0, e
	}
	if race.Enabled {
		if done > 0 {
			race.WriteRange(unsafe.Pointer(&p[0]), int(done))
		}
		race.Acquire(unsafe.Pointer(&ioSync))
	}
	if msanenabled && done > 0 {
		msanWrite(unsafe.Pointer(&p[0]), int(done))
	}
	return int(done), nil
}

func Write(fd Handle, p []byte) (n int, err error) {
	if race.Enabled {
		race.ReleaseMerge(unsafe.Pointer(&ioSync))
	}
	var done uint32
	e := WriteFile(fd, p, &done, nil)
	if e != nil {
		return 0, e
	}
	if race.Enabled && done > 0 {
		race.ReadRange(unsafe.Pointer(&p[0]), int(done))
	}
	if msanenabled && done > 0 {
		msanRead(unsafe.Pointer(&p[0]), int(done))
	}
	return int(done), nil
}

var ioSync int64

var procSetFilePointerEx = modkernel32.NewProc("SetFilePointerEx")

const ptrSize = unsafe.Sizeof(uintptr(0))

// setFilePointerEx调用setFilePointerEx.
// 请参阅https:
func setFilePointerEx(handle Handle, distToMove int64, newFilePointer *int64, whence uint32) error {
	var e1 Errno
	if unsafe.Sizeof(uintptr(0)) == 8 {
		_, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 4, uintptr(handle), uintptr(distToMove), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0, 0)
	} else {
		// 不同的32位系统对distToMove是否开始8字节对齐表示不满。
		switch runtime.GOARCH {
		default:
			panic("unsupported 32-bit architecture")
		case "386":
			// distToMove是一个大整数：
			// https:
			_, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 5, uintptr(handle), uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence), 0)
		case "arm":
			// distToMove必须按照ARM调用约定8字节对齐
			// https:
			_, _, e1 = Syscall6(procSetFilePointerEx.Addr(), 6, uintptr(handle), 0, uintptr(distToMove), uintptr(distToMove>>32), uintptr(unsafe.Pointer(newFilePointer)), uintptr(whence))
		}
	}
	if e1 != 0 {
		return errnoErr(e1)
	}
	return nil
}

func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
	var w uint32
	switch whence {
	case 0:
		w = FILE_BEGIN
	case 1:
		w = FILE_CURRENT
	case 2:
		w = FILE_END
	}
	// 使用GetFileType检查k pipe，pipe不能做seek 
	ft, _ := GetFileType(fd)
	if ft == FILE_TYPE_PIPE {
		return 0, ESPIPE
	}
	err = setFilePointerEx(fd, offset, &newoffset, w)
	return
}

func Close(fd Handle) (err error) {
	return CloseHandle(fd)
}

var (
	Stdin  = getStdHandle(STD_INPUT_HANDLE)
	Stdout = getStdHandle(STD_OUTPUT_HANDLE)
	Stderr = getStdHandle(STD_ERROR_HANDLE)
)

func getStdHandle(h int) (fd Handle) {
	r, _ := GetStdHandle(h)
	return r
}

const ImplementsGetwd = true

func Getwd() (wd string, err error) {
	b := make([]uint16, 300)
	n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
	if e != nil {
		return "", e
	}
	return string(utf16.Decode(b[0:n])), nil
}

func Chdir(path string) (err error) {
	pathp, err := UTF16PtrFromString(path)
	if err != nil {
		return err
	}
	return SetCurrentDirectory(pathp)
}

func Mkdir(path string, mode uint32) (err error) {
	pathp, err := UTF16PtrFromString(path)
	if err != nil {
		return err
	}
	return CreateDirectory(pathp, nil)
}

func Rmdir(path string) (err error) {
	pathp, err := UTF16PtrFromString(path)
	if err != nil {
		return err
	}
	return RemoveDirectory(pathp)
}

func Unlink(path string) (err error) {
	pathp, err := UTF16PtrFromString(path)
	if err != nil {
		return err
	}
	return DeleteFile(pathp)
}

func Rename(oldpath, newpath string) (err error) {
	from, err := UTF16PtrFromString(oldpath)
	if err != nil {
		return err
	}
	to, err := UTF16PtrFromString(newpath)
	if err != nil {
		return err
	}
	return MoveFile(from, to)
}

func ComputerName() (name string, err error) {
	var n uint32 = MAX_COMPUTERNAME_LENGTH + 1
	b := make([]uint16, n)
	e := GetComputerName(&b[0], &n)
	if e != nil {
		return "", e
	}
	return string(utf16.Decode(b[0:n])), nil
}

func Ftruncate(fd Handle, length int64) (err error) {
	curoffset, e := Seek(fd, 0, 1)
	if e != nil {
		return e
	}
	defer Seek(fd, curoffset, 0)
	_, e = Seek(fd, length, 0)
	if e != nil {
		return e
	}
	e = SetEndOfFile(fd)
	if e != nil {
		return e
	}
	return nil
}

func Gettimeofday(tv *Timeval) (err error) {
	var ft Filetime
	GetSystemTimeAsFileTime(&ft)
	*tv = NsecToTimeval(ft.Nanoseconds())
	return nil
}

func Pipe(p []Handle) (err error) {
	if len(p) != 2 {
		return EINVAL
	}
	var r, w Handle
	e := CreatePipe(&r, &w, makeInheritSa(), 0)
	if e != nil {
		return e
	}
	p[0] = r
	p[1] = w
	return nil
}

func Utimes(path string, tv []Timeval) (err error) {
	if len(tv) != 2 {
		return EINVAL
	}
	pathp, e := UTF16PtrFromString(path)
	if e != nil {
		return e
	}
	h, e := CreateFile(pathp,
		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
	if e != nil {
		return e
	}
	defer Close(h)
	a := NsecToFiletime(tv[0].Nanoseconds())
	w := NsecToFiletime(tv[1].Nanoseconds())
	return SetFileTime(h, nil, &a, &w)
}

func UtimesNano(path string, ts []Timespec) (err error) {
	if len(ts) != 2 {
		return EINVAL
	}
	pathp, e := UTF16PtrFromString(path)
	if e != nil {
		return e
	}
	h, e := CreateFile(pathp,
		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
	if e != nil {
		return e
	}
	defer Close(h)
	a := NsecToFiletime(TimespecToNsec(ts[0]))
	w := NsecToFiletime(TimespecToNsec(ts[1]))
	return SetFileTime(h, nil, &a, &w)
}

func Fsync(fd Handle) (err error) {
	return FlushFileBuffers(fd)
}

func Chmod(path string, mode uint32) (err error) {
	p, e := UTF16PtrFromString(path)
	if e != nil {
		return e
	}
	attrs, e := GetFileAttributes(p)
	if e != nil {
		return e
	}
	if mode&S_IWRITE != 0 {
		attrs &^= FILE_ATTRIBUTE_READONLY
	} else {
		attrs |= FILE_ATTRIBUTE_READONLY
	}
	return SetFileAttributes(p, attrs)
}

func LoadCancelIoEx() error {
	return procCancelIoEx.Find()
}

func LoadSetFileCompletionNotificationModes() error {
	return procSetFileCompletionNotificationModes.Find()
}

// net api调用

const socket_error = uintptr(^uint32(0))

// sys WSAStartup（verreq uint32，data*WSAData）（sockerr error）=ws2_32.WSAStartup 
// sys WSACleanup（）（error）[failretval==socket error]=ws2_32.WSACleanup 
// sys WSAIoctl（s句柄，iocc uint32，inbuf*字节，cbif uint32，EXBUF*字节，cbob uint32，cbbr*uint32，重叠*重叠，完成例程uintptr）（err err error）[failretval==socket\U error]=ws2\U 32.WSAIoctl 
// sys socket（af int32，typ int32，协议int32）（句柄，err err error）[failretval==InvalidHandle]=ws2_32.socket 
// sys Setsockopt（s Handle，level int32，optname int32，optval*byte，optlen int32）（error error）[failretval==socket_error]=ws2_32.Setsockopt 
// sys Getsockopt（s Handle，level int32，optname int32，optval*byte，opttlen*int32）（error）[failretval==socket error]=ws2_32.getsockopt 
// sys-bind（s-Handle，name-unsafe.Pointer，namelen-int32）（错误）[failretval==socket\u-error]=ws2_32.bind 
// sys-connect（s-Handle，name-unsafe.Pointer，namelen-int32）（错误）[failretval==socket\u-error]=ws2\u-32.connect 
// sys getpeername（s Handle，rsa*RawSockaddrAny，addrlen*int32）（error error）[failretval==socket\u error]=ws2\u 32.getpeername 
// sys listen（s Handle，backlog int32）（error error）[failretval==socket\u error]=ws2\u 32.listen 
// sys Closesocket（s Handle）（错误）[failretval==socket_error]=ws2_32.Closesocket 
// /sys AcceptEx（ls Handle，as Handle，as Handle，buf*byte，rxdata uint32，laddrlen uint32，raddrlen uint32，recvd*uint32，overlapped*overlapped）（错误）=mswsock.AcceptEx 
// sys GetAcceptExSockaddrs（buf*字节，rxdata单元32，laddrlen单元32，raddrlen单元32，lrsa**RawSockaddrAny，lrsalen*int32，rrsa**RawSockaddrAny，rrsalen*int32）=mswsock.GetAcceptExSockaddrs 
// sys WSASend（s Handle，bufs*WSABuf，bufcnt uint32，sent*uint32，flags uint32，flags uint32，overlapped*overlapped*overlapped，crudtine*crot*crudtine）（错误）[failretval==socket]=ws2_32.WSASend 
// sys WSARecvFrom（s Handle，bufs*WSABuf，bufcnt uint32，recvd*uint32，flags*uint32，from*RawSockaddrAny，from*RawSockaddrAny，from*int32，overlapped*overlapped，croutine*byte）（error）[failretval==socket\u error]=ws2_32.WSARecvFrom 
// sys GetServByName（名称字符串，原型字符串）（s*Servent，err error）[failretval==nil]=ws2_32.GetServByName 
// sys Ntohs（netshort uint16）（u uint16）=ws2_32.Ntohs 
// sys dnsrecordlist free（名称字符串，qtype uint16，选项uint32，额外*字节，qrs**DNSRecord，pr*字节）（状态错误）=dnsapi.DnsQuery W 
// sys dnsrecordlist free（rl*dnsrecorde，freetype uint32）=dnsapi.dnsrecordlist free 
// DnsNameCompare（名称1*uint16，name2*uint16）（相同bool）=dnsapi.DnsNameCompare\u 
// sys GetAddrInfoW（nodename*uint16，servicename*uint16，hits*AddrinfoW，result**AddrinfoW）（sockerr error）=ws2_32.GetAddrInfoW 
// sys FreeAddrInfoW（addrinfo*AddrinfoW）=ws2_32.FreeAddrInfoW 
// sys getadapterInfo（ai*IpAdapterInfo，ol*uint32）（错误代码错误）=iphlapi.getadapterInfo 
// sys SetFileCompletionNotificationModes（句柄句柄，标志uint8）（错误）=kernel32.SetFileCompletionNotificationModes 
// sys WSAEnumProtocols（协议*int32，协议缓冲区*WSAProtocolInfo，缓冲区长度*uint32）（n int32，错误）[failretval==-1]=ws2_32.WSAEnumProtocolsW 

// 用于测试：客户端可以设置此标志强制
// 创建IPv6套接字以返回EAFNOSUPPORT.
var SocketDisableIPv6 bool

type RawSockaddrInet4 struct {
	Family uint16
	Port   uint16
	Addr   [4]byte /* in_addr */
	Zero   [8]uint8
}

type RawSockaddrInet6 struct {
	Family   uint16
	Port     uint16
	Flowinfo uint32
	Addr     [16]byte /* in6_addr */
	Scope_id uint32
}

type RawSockaddr struct {
	Family uint16
	Data   [14]int8
}

type RawSockaddrAny struct {
	Addr RawSockaddr
	Pad  [100]int8
}

type Sockaddr interface {
	sockaddr() (ptr unsafe.Pointer, len int32, err error) // 小写；只有我们可以定义Sockaddrs 
}

type SockaddrInet4 struct {
	Port int
	Addr [4]byte
	raw  RawSockaddrInet4
}

func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) {
	if sa.Port < 0 || sa.Port > 0xFFFF {
		return nil, 0, EINVAL
	}
	sa.raw.Family = AF_INET
	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
	p[0] = byte(sa.Port >> 8)
	p[1] = byte(sa.Port)
	for i := 0; i < len(sa.Addr); i++ {
		sa.raw.Addr[i] = sa.Addr[i]
	}
	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
}

type SockaddrInet6 struct {
	Port   int
	ZoneId uint32
	Addr   [16]byte
	raw    RawSockaddrInet6
}

func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
	if sa.Port < 0 || sa.Port > 0xFFFF {
		return nil, 0, EINVAL
	}
	sa.raw.Family = AF_INET6
	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
	p[0] = byte(sa.Port >> 8)
	p[1] = byte(sa.Port)
	sa.raw.Scope_id = sa.ZoneId
	for i := 0; i < len(sa.Addr); i++ {
		sa.raw.Addr[i] = sa.Addr[i]
	}
	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
}

type RawSockaddrUnix struct {
	Family uint16
	Path   [UNIX_PATH_MAX]int8
}

type SockaddrUnix struct {
	Name string
	raw  RawSockaddrUnix
}

func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
	name := sa.Name
	n := len(name)
	if n > len(sa.raw.Path) {
		return nil, 0, EINVAL
	}
	if n == len(sa.raw.Path) && name[0] != '@' {
		return nil, 0, EINVAL
	}
	sa.raw.Family = AF_UNIX
	for i := 0; i < n; i++ {
		sa.raw.Path[i] = int8(name[i])
	}
	// 长度为family（uint16），name，num.
	sl := int32(2)
	if n > 0 {
		sl += int32(n) + 1
	}
	if sa.raw.Path[0] == '@' {
		sa.raw.Path[0] = 0
		// 不计算抽象地址的尾随NUL。
		sl--
	}

	return unsafe.Pointer(&sa.raw), sl, nil
}

func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
	switch rsa.Addr.Family {
	case AF_UNIX:
		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
		sa := new(SockaddrUnix)
		if pp.Path[0] == 0 {
			// “抽象”Unix域套接字。
			// 将前导NUL重写为@以进行文本显示。
			// （这是标准约定。）
			// 不适合就地覆盖，
			// 但是下面的调用方不关心。
			pp.Path[0] = '@'
		}

		// 假设路径以NUL结尾。
		// 这在技术上不是
		// 抽象Unix域套接字的Linux语义——它们应该是
		// 不奇怪-调整二进制blob的大小——但
		// 每个人都使用此约定。
		n := 0
		for n < len(pp.Path) && pp.Path[n] != 0 {
			n++
		}
		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n:n]
		sa.Name = string(bytes)
		return sa, nil

	case AF_INET:
		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
		sa := new(SockaddrInet4)
		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
		sa.Port = int(p[0])<<8 + int(p[1])
		for i := 0; i < len(sa.Addr); i++ {
			sa.Addr[i] = pp.Addr[i]
		}
		return sa, nil

	case AF_INET6:
		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
		sa := new(SockaddrInet6)
		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
		sa.Port = int(p[0])<<8 + int(p[1])
		sa.ZoneId = pp.Scope_id
		for i := 0; i < len(sa.Addr); i++ {
			sa.Addr[i] = pp.Addr[i]
		}
		return sa, nil
	}
	return nil, EAFNOSUPPORT
}

func Socket(domain, typ, proto int) (fd Handle, err error) {
	if domain == AF_INET6 && SocketDisableIPv6 {
		return InvalidHandle, EAFNOSUPPORT
	}
	return socket(int32(domain), int32(typ), int32(proto))
}

func SetsockoptInt(fd Handle, level, opt int, value int) (err error) {
	v := int32(value)
	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v)))
}

func Bind(fd Handle, sa Sockaddr) (err error) {
	ptr, n, err := sa.sockaddr()
	if err != nil {
		return err
	}
	return bind(fd, ptr, n)
}

func Connect(fd Handle, sa Sockaddr) (err error) {
	ptr, n, err := sa.sockaddr()
	if err != nil {
		return err
	}
	return connect(fd, ptr, n)
}

func Getsockname(fd Handle) (sa Sockaddr, err error) {
	var rsa RawSockaddrAny
	l := int32(unsafe.Sizeof(rsa))
	if err = getsockname(fd, &rsa, &l); err != nil {
		return
	}
	return rsa.Sockaddr()
}

func Getpeername(fd Handle) (sa Sockaddr, err error) {
	var rsa RawSockaddrAny
	l := int32(unsafe.Sizeof(rsa))
	if err = getpeername(fd, &rsa, &l); err != nil {
		return
	}
	return rsa.Sockaddr()
}

func Listen(s Handle, n int) (err error) {
	return listen(s, int32(n))
}

func Shutdown(fd Handle, how int) (err error) {
	return shutdown(fd, int32(how))
}

func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
	rsa, len, err := to.sockaddr()
	if err != nil {
		return err
	}
	r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(rsa)), uintptr(len), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
	if r1 == socket_error {
		if e1 != 0 {
			err = errnoErr(e1)
		} else {
			err = EINVAL
		}
	}
	return err
}

func LoadGetAddrInfo() error {
	return procGetAddrInfoW.Find()
}

var connectExFunc struct {
	once sync.Once
	addr uintptr
	err  error
}

func LoadConnectEx() error {
	connectExFunc.once.Do(func() {
		var s Handle
		s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
		if connectExFunc.err != nil {
			return
		}
		defer CloseHandle(s)
		var n uint32
		connectExFunc.err = WSAIoctl(s,
			SIO_GET_EXTENSION_FUNCTION_POINTER,
			(*byte)(unsafe.Pointer(&WSAID_CONNECTEX)),
			uint32(unsafe.Sizeof(WSAID_CONNECTEX)),
			(*byte)(unsafe.Pointer(&connectExFunc.addr)),
			uint32(unsafe.Sizeof(connectExFunc.addr)),
			&n, nil, 0)
	})
	return connectExFunc.err
}

func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) {
	r1, _, e1 := Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0)
	if r1 == 0 {
		if e1 != 0 {
			err = error(e1)
		} else {
			err = EINVAL
		}
	}
	return
}

func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error {
	err := LoadConnectEx()
	if err != nil {
		return errorspkg.New("failed to find ConnectEx: " + err.Error())
	}
	ptr, n, err := sa.sockaddr()
	if err != nil {
		return err
	}
	return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
}

// 发明的结构支持软件包操作系统所期望的内容。
type Rusage struct {
	CreationTime Filetime
	ExitTime     Filetime
	KernelTime   Filetime
	UserTime     Filetime
}

type WaitStatus struct {
	ExitCode uint32
}

func (w WaitStatus) Exited() bool { return true }

func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }

func (w WaitStatus) Signal() Signal { return -1 }

func (w WaitStatus) CoreDump() bool { return false }

func (w WaitStatus) Stopped() bool { return false }

func (w WaitStatus) Continued() bool { return false }

func (w WaitStatus) StopSignal() Signal { return -1 }

func (w WaitStatus) Signaled() bool { return false }

func (w WaitStatus) TrapCause() int { return -1 }

// Timespec是Windows上发明的结构，但这里用于
// 与其他操作系统的syscall包的一致性。
type Timespec struct {
	Sec  int64
	Nsec int64
}

func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }

func NsecToTimespec(nsec int64) (ts Timespec) {
	ts.Sec = nsec / 1e9
	ts.Nsec = nsec % 1e9
	return
}

// TODO（brainman）：修复网络所需的全部

func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, EWINDOWS }
func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
	return 0, nil, EWINDOWS
}
func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error)       { return EWINDOWS }
func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return EWINDOWS }

// Linger结构错误，但我们只在Go 1之后注意到。
// sysLinger是真正的系统调用结构。

// BUG（brainman）：Linger的定义不适合直接与Setsockopt和Getsockopt一起使用
// 
// 请改用SetsockoptLinger。

type Linger struct {
	Onoff  int32
	Linger int32
}

type sysLinger struct {
	Onoff  uint16
	Linger uint16
}

type IPMreq struct {
	Multiaddr [4]byte /* in_addr */
	Interface [4]byte /* in_addr */
}

type IPv6Mreq struct {
	Multiaddr [16]byte /* in6_addr */
	Interface uint32
}

func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, EWINDOWS }

func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
	sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys)))
}

func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
}
func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
}
func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { return EWINDOWS }

func Getpid() (pid int) { return int(getCurrentProcessId()) }

func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
	// 注意（rsc）：Win32finddata结构对于系统调用是错误的：
	// 这两条路径都是短的。请使用正确的结构
	// win32finddata1，然后将结果复制出来。
	// 此处没有表现力损失，因为如果使用最终
	// uint16，则应为NUL，Go不需要。
	// 对于Go 1.1，我们可以通过在结构中添加最后一个Bug[2]uint16字段，然后直接调整结果中的字段，从而避免在此处分配win32finddata1。
	var data1 win32finddata1
	handle, err = findFirstFile1(name, &data1)
	if err == nil {
		copyFindData(data, &data1)
	}
	return
}

func FindNextFile(handle Handle, data *Win32finddata) (err error) {
	var data1 win32finddata1
	err = findNextFile1(handle, &data1)
	if err == nil {
		copyFindData(data, &data1)
	}
	return
}

func getProcessEntry(pid int) (*ProcessEntry32, error) {
	snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
	if err != nil {
		return nil, err
	}
	defer CloseHandle(snapshot)
	var procEntry ProcessEntry32
	procEntry.Size = uint32(unsafe.Sizeof(procEntry))
	if err = Process32First(snapshot, &procEntry); err != nil {
		return nil, err
	}
	for {
		if procEntry.ProcessID == uint32(pid) {
			return &procEntry, nil
		}
		err = Process32Next(snapshot, &procEntry)
		if err != nil {
			return nil, err
		}
	}
}

func Getppid() (ppid int) {
	pe, err := getProcessEntry(Getpid())
	if err != nil {
		return -1
	}
	return int(pe.ParentProcessID)
}

// TODO（brainman）：修复操作系统所需的全部
func Fchdir(fd Handle) (err error)             { return EWINDOWS }
func Link(oldpath, newpath string) (err error) { return EWINDOWS }
func Symlink(path, link string) (err error)    { return EWINDOWS }

func Fchmod(fd Handle, mode uint32) (err error)        { return EWINDOWS }
func Chown(path string, uid int, gid int) (err error)  { return EWINDOWS }
func Lchown(path string, uid int, gid int) (err error) { return EWINDOWS }
func Fchown(fd Handle, uid int, gid int) (err error)   { return EWINDOWS }

func Getuid() (uid int)                  { return -1 }
func Geteuid() (euid int)                { return -1 }
func Getgid() (gid int)                  { return -1 }
func Getegid() (egid int)                { return -1 }
func Getgroups() (gids []int, err error) { return nil, EWINDOWS }

type Signal int

func (s Signal) Signal() {}

func (s Signal) String() string {
	if 0 <= s && int(s) < len(signals) {
		str := signals[s]
		if str != "" {
			return str
		}
	}
	return "signal " + itoa.Itoa(int(s))
}

func LoadCreateSymbolicLink() error {
	return procCreateSymbolicLinkW.Find()
}

// Readlink返回命名符号链接的目标。
func Readlink(path string, buf []byte) (n int, err error) {
	fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING,
		FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0)
	if err != nil {
		return -1, err
	}
	defer CloseHandle(fd)

	rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
	var bytesReturned uint32
	err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
	if err != nil {
		return -1, err
	}

	rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
	var s string
	switch rdb.ReparseTag {
	case IO_REPARSE_TAG_SYMLINK:
		data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
		p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
		s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
		if data.Flags&_SYMLINK_FLAG_RELATIVE == 0 {
			if len(s) >= 4 && s[:4] == `\??\` {
				s = s[4:]
				switch {
				case len(s) >= 2 && s[1] == ':': // /\？？\C:\foo\bar 
					// 什么也不做
				case len(s) >= 4 && s[:4] == `UNC\`: // /\？？\UNC\foo\bar 
					s = `\\` + s[4:]
				default:
					// 意外；不要做任何出乎意料的事；不做任何事
				}
			} else {
			}
		}
	case _IO_REPARSE_TAG_MOUNT_POINT:
		data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
		p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
		s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
			s = s[4:]
		} else {
		}
	default:
		// 路径不是符号链接或连接，而是另一种类型的重新分析
		// 点
		return -1, ENOENT
	}
	n = copy(buf, []byte(s))

	return n, nil
}

// 已弃用：CreateIoCompletionPort具有错误的函数签名。使用x/sys/windows.CreateIoCompletionPort。
func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (Handle, error) {
	return createIoCompletionPort(filehandle, cphandle, uintptr(key), threadcnt)
}

// 已弃用：GetQueuedCompletionStatus具有错误的函数签名。使用x/sys/windows.GetQueuedCompletionStatus。
func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) error {
	var ukey uintptr
	var pukey *uintptr
	if key != nil {
		ukey = uintptr(*key)
		pukey = &ukey
	}
	err := getQueuedCompletionStatus(cphandle, qty, pukey, overlapped, timeout)
	if key != nil {
		*key = uint32(ukey)
		if uintptr(*key) != ukey && err == nil {
			err = errorspkg.New("GetQueuedCompletionStatus returned key overflow")
		}
	}
	return err
}

// 已弃用：PostQueuedCompletionStatus具有错误的函数签名。使用x/sys/windows.PostQueuedCompletionStatus。
func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) error {
	return postQueuedCompletionStatus(cphandle, qty, uintptr(key), overlapped)
}

// newProcThreadAttributeList分配新的进程线程属性列表，其中
// 请求的最大属性数，必须由
// deleteProcThreadAttributeList清除。
func newProcThreadAttributeList(maxAttrCount uint32) (*_PROC_THREAD_ATTRIBUTE_LIST, error) {
	var size uintptr
	err := initializeProcThreadAttributeList(nil, maxAttrCount, 0, &size)
	if err != ERROR_INSUFFICIENT_BUFFER {
		if err == nil {
			return nil, errorspkg.New("unable to query buffer size from InitializeProcThreadAttributeList")
		}
		return nil, err
	}
	// 尺寸保证为≥1通过初始化OcthreadAttributeList。
	al := (*_PROC_THREAD_ATTRIBUTE_LIST)(unsafe.Pointer(&make([]byte, size)[0]))
	err = initializeProcThreadAttributeList(al, maxAttrCount, 0, &size)
	if err != nil {
		return nil, err
	}
	return al, nil
}
